package com.nebula.item.service.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.plugins.Page;
import com.nebula.item.pojo.utils.pojo.User;
import com.nebula.item.service.exception.RocketMQException;
import com.nebula.item.service.service.Selectservice;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;

/**
 * @Author: WangZhongLiang
 * @Date: 2019/9/2
 */
@Slf4j
@CacheConfig(cacheNames = "cache")
@RestController
@RequestMapping("/select")
public class selectcontroller {

    @Autowired
    AmqpTemplate amqpTemplate;

    @Autowired
//    Selectservice selectservice;

    @Value("${rocketmq.producer.groupName}")
    private String groupName;

    @Value("${rocketmq.producer.namesrvAddr}")
    private String namesrvAddr;

    @Value("${rocketmq.producer.topic}")
    private String topic;

    @Value("${rocketmq.producer.tag}")
    private String tag;


    @GetMapping("/user")
    public String user(){
        String a = "王司徒2";
        String b = "select";
        sendMessage(a,b);
        return a;
    }

    @GetMapping("/getIp")
    public String getIp(HttpServletRequest request) throws UnknownHostException {
        String ipAddress1 = request.getHeader("X-Real-IP");
        String ipAddress2 = request.getHeader("X-Forwarded-For");
        String ipAddress3 = getIpAddress(request);
        String ipAddress4 = request.getRemoteAddr();
        String ipAddress5 = request.getHeader("Host");
        InetAddress inetAddress = InetAddress.getLocalHost();
        //ip地址
        String ipAddress6 = inetAddress.getHostAddress();

        String ipAddress7 = getClientIp(request);
        String ipAddress8 = getRemortIP(request);
        String ipAddress9 = getIpAddr(request);
        String ipAddress10 = getIpAddrr(request);

        System.out.println("ipAddress1:"+ipAddress1);
        System.out.println("ipAddress2:"+ipAddress2);
        System.out.println("ipAddress3:"+ipAddress3);
        System.out.println("ipAddress4:"+ipAddress4);
        System.out.println("ipAddress5:"+ipAddress5);
        System.out.println("ipAddress6:"+ipAddress6);
        System.out.println("ipAddress7:"+ipAddress7);
        System.out.println("ipAddress8:"+ipAddress8);
        System.out.println("ipAddress9:"+ipAddress9);
        System.out.println("ipAddress10:"+ipAddress10);
        return ipAddress1;
    }

    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (!StringUtils.isEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    public String getRemortIP(HttpServletRequest request) {
        if (request.getHeader("x-forwarded-for") == null) {
            return request.getRemoteAddr();
        }
        return request.getHeader("x-forwarded-for");
    }

    public String getIpAddr(HttpServletRequest request) {
        String ip= request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 获取当前网络ip
     * @param request
     * @return
     */
    public String getIpAddrr(HttpServletRequest request){
        String ipAddress = request.getHeader("x-forwarded-for");
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
                //根据网卡取本机配置的IP
                InetAddress inet=null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress= inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
            if(ipAddress.indexOf(",")>0){
                ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }

    public String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }


    /*@GetMapping("/page")
    @Cacheable(value = "cache01",key =  "targetclass+selectPageController+#p0",condition= "#map.size()>0",unless = "#map.size<0")
    public Page selectPageController(@RequestParam Map<String,Object> map){
        Page<Map<String, Object>> page = selectservice.selectPageService(map);
        return page;
    }

    @GetMapping("/page")
    //缓存更新，要与@Cacheable的value与key相同
    @Cacheable(value = "cache01",key =  "targetclass+selectPageController+#p0")
    public Page UpdateController(@RequestParam Map<String,Object> map){
        Page<Map<String, Object>> page = selectservice.selectPageService(map);
        return page;
    }*/

    private void sendMessage(String news,String type){
        try {
            amqpTemplate.convertAndSend("item."+type,news);
            System.out.println("rabbitmq发送的消息是："+news);
        } catch (AmqpException e) {
            log.error("发送消息异常",type,news,e);
        }
    }

    @GetMapping("/rocketMQ")
    @CacheEvict(value = "cache02",allEntries = true)
    public void ceRocketMq() throws RocketMQException {
        if(StringUtils.isBlank(groupName)){
            throw new RocketMQException("groupName不能为空!");
        }
        if(StringUtils.isBlank(namesrvAddr)){
            throw new RocketMQException("namesrvAddr不能为空");
        }
        if(StringUtils.isBlank(topic)){
            throw new RocketMQException("topic不能为空");
        }
        if (StringUtils.isBlank(tag)){
            throw new RocketMQException("tag不能为空");
        }

        //注意的是这个producer一个程序里面只能出现一个，当重复创建时就会报错
        DefaultMQProducer producer = new DefaultMQProducer(groupName);
        producer.setNamesrvAddr(namesrvAddr);
        try {
            // 在发送消息前，必须调用 start 方法来启动 Producer，只需调用一次即可
            producer.start();
            for (int i = 0; i < 5; i++) {
                User user = new User();
                user.setUsername("axl"+i);
                user.setPassword("123"+i);
                String str = JSON.toJSONString(user);
                // 任何二进制形式的数据， 消息队列 MQ 不做任何干预，
                // 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
                //Message 消息存储的载体，消息绑定的topic,tag，以bytes的形式发送消息
                Message message = new Message(topic,tag,str.getBytes(RemotingHelper.DEFAULT_CHARSET));
                /*注意：send方法是同步调用，只要不抛异常就标识成功。但是发送成功也可会有多种状态,
                例如消息写入Master成功，但是Slave不成功，这种情况消息属于成功，但是对于个别应用如果对消息可靠性要求极高，
                需要对这种情况做处理。另外，消息可能会存在发送失败的情况，失败重试由应用来处理。*/
                System.out.println("消息发出:"+str);
                SendResult send = producer.send(message);

                /*//指定消息投递的0这个队列，同步的方式，会有返回结果
                SendResult sendResult = producer.send(message, new MessageQueueSelector() {
                    @Override
                    public MessageQueue select(List<MessageQueue> queues, Message msg, Object queNum) {
                        int queueNum = Integer.parseInt(queNum.toString());
                        return queues.get(queueNum);
                    }
                }, 0);*/

                System.out.println("发送响应：MsgId:" + send.getMsgId() + "，发送状态:" + send.getSendStatus());
                System.out.println("当前消息投递的队列是:"+send.getMessageQueue().getQueueId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //应用退出时，要调用shutdown来清理资源，关闭网络连接，从MetaQ服务器上注销自己
            producer.shutdown();
        }
    }
}
